package com.hrt.datasender.datasent.onenet;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;

import javax.comm.CommPortIdentifier;
import javax.comm.NoSuchPortException;
import javax.comm.PortInUseException;
import javax.comm.SerialPort;

import org.apache.commons.lang3.text.StrBuilder;

import com.btcode.common.MyLog;
import com.btcode.common.PropertiesUnit;
import com.btcode.log.ILog;
import com.hrt.datasender.dataschedule.OneNetScheduler;
import com.hrt.datasender.mq.MqKit;
import com.hrt.datasender.mq.model.MqModel;
import com.hrt.datasender.mq.model.PacketModel;


/**
 *
 * <pre>
 * 注释
 * </pre>
 * @author FAN
 * @date 2018年10月24日下午4:31:37
 */
public class OneNetSender {

	public static ILog log;

	private static OneNetSender _instance;

	private OutputStream os;
	private InputStream is;
	public static OneNetRead read = new OneNetRead();
	OneNetScheduler res = new OneNetScheduler();


	public static OneNetSender getInstance() {
        if (_instance == null) {
            _instance = new OneNetSender();
        }
        return _instance;
    }



	public void openSerial() throws Exception {

		String port = PropertiesUnit.getValue("port");

		int baudRate = PropertiesUnit.getInt("CommBps");   //波特率
		int dataBit = PropertiesUnit.getInt("CommData");  //数据位
		int stopBit = PropertiesUnit.getInt("CommStop");   //停止位
		int parity = PropertiesUnit.getInt("CommParity");  //校验位

		log.info(port);
		log.info(baudRate);
		log.info(dataBit);
		log.info(stopBit);
		log.info(parity);

		CommPortIdentifier portId = CommPortIdentifier.getPortIdentifier(port);
		SerialPort sPort = (SerialPort) portId.open(port, 2000);

		sPort.setSerialPortParams(baudRate,
				dataBit,
				stopBit,
				parity);

		is = new BufferedInputStream(sPort.getInputStream());
		os = sPort.getOutputStream();

	}

	public void askSerialData(OutputStream os) throws NoSuchPortException, PortInUseException, IOException, InterruptedException {

		String at = "at\r";
		String zc = "AT+MIPLCONF=71,00030000805101001900636F61703A2F2F3231382E31372E31362E3136353A353638331F003836353832303033313730333339353B343630303432353631393032333630050501,1,1\r";
		String ec = "AT+MIPLADDOBJ=0,3336,0\r";
		String opec = "AT+MIPLOPEN=0,15\r";
		String optest = "AT+MIPLOPEN?\r";


		byte [] byat = at.getBytes();
		byte [] byzc = zc.getBytes();
		byte [] byec = ec.getBytes();
		byte [] byopec = opec.getBytes();
		byte [] byoptest = optest.getBytes();


		os.write(byat);

		Thread.sleep(2000);

		String msg = read.getArrMsg().get(0);

		String open = "+MIPLOPEN";

		String msgs = "";


		if (!"OK".equals(msg)) {

			read.getArrMsg().clear();
			os.write(byat);
			Thread.sleep(2000);

		}else {
			System.out.println("设备正常");


			os.write(byoptest);//询问NB-IOT串口通道是否正常，若返回数据中带有+MIPLOPEN:0,1则表示通道正常

			Thread.sleep(3000);

			List<String>  list = read.getArrMsg();

			StringBuffer stringBuffer = new StringBuffer();

			for (int i = 0; i < list.size(); i++) {

				stringBuffer.append(list.get(i));
			}

			String str = stringBuffer.toString();

			log.info(str);

			if (!"OKERROR".equals(str)) {

				for (int i = 0; i < list.size(); i++) {

					if (list.get(i).contains(open)) {
						int iopen = list.get(i).indexOf(open);
						msgs = list.get(i).substring(iopen,iopen+13);

						if ("+MIPLOPEN:0,1".equals(msgs)) {
							log.info("通道正常");
							customerDataMQ();
							customerRefreshRegisterMQ();
						}
					}
				}

			}else {

				read.getArrMsg().clear();
				os.write(byzc);
				Thread.sleep(2000);
				msg = read.getArrMsg().get(0);

				if ("0\r\n\r\nOK".equals(msg)) {

					read.getArrMsg().clear();
					os.write(byec);
					Thread.sleep(2000);
					msg = read.getArrMsg().get(0);

					if ("OK\r\n\nOK".equals(msg)) {

						read.getArrMsg().clear();
						os.write(byopec);
						Thread.sleep(5000);

						List<String>  listStr = read.getArrMsg();

						for (int j = 0; j < listStr.size(); j++) {

							if (listStr.get(j).contains(open)) {
								int jopen = listStr.get(j).indexOf(open);
								msgs = listStr.get(j).substring(jopen,jopen+13);

								if ("+MIPLOPEN:0,1".equals(msgs)) {
									customerDataMQ();
									customerRefreshRegisterMQ();

								}
							}
						}
					}

				}

			}
		}
	}

	public static void customerDataMQ(){

		OneNetManager oneNetManager = OneNetManager.getInstance();

        MqKit.consumeMsgFromBizDataMQ(new MqKit.MsgListener() {
            @Override
            public void onReceive(MqModel mqModel) {
                try {

                	PacketModel model = (PacketModel)mqModel;
                	log.info("准备发送数据:" + model.getMsg());
                	oneNetManager.sendMsg(model);
                } catch (Exception e) {
                    log.error("发送业务消息包错误：", e);
                }
            }
        });
    }


	public static void customerRefreshRegisterMQ() {

		MqKit.consumeMsgFromRefreshRegisterMQ(new MqKit.MsgListener() {

			String open = "+MIPLUPDATE";
			String msgs = "";

			@Override
			public void onReceive(MqModel mqModel) {
				PacketModel model = (PacketModel)mqModel;
            	log.info("准备刷新注册码时间:" + model.getMsg());
            	OneNetManager.getInstance().sendRefreshRegisterMsg(model);

            	try {
					Thread.sleep(2000);

	            	List<String>  listStr = read.getArrMsg();

	            	for (int j = 0; j < listStr.size(); j++) {

	        			if (listStr.get(j).contains(open)) {
	        				int jopen = listStr.get(j).indexOf(open);
	        				msgs = listStr.get(j).substring(jopen,jopen+15);


	        				if ("+MIPLUPDATE:0,1".equals(msgs)) {
	        					log.info("刷新注册时间成功");
	        				}else {
	        					log.error("刷新注册时间失败");
	        				}
	        			}
	        		}

            	} catch (InterruptedException e) {
					e.printStackTrace();
					log.error("注册码报错:",e);
				}

			}
		});
	}

	public void start() throws Exception {

		log = MyLog.getInstance().getLogger(OneNetSender.class.getName());

		openSerial();
		read.setIs(is);
		read.start();
		OneNetManager.getInstance().setOs(os);
		askSerialData(os);

	}
}
